#include "log/log.h"
#include "smart/smart_drm.hpp"
#include "../mpp/smart/h264_file_nalu_pars.h"
#include "../mpp/smart/smart_mpp_decoder.hpp"
#include "rga_wrapper.h"
#include "clocker/timer.hpp"

FILE* fp;

int main(const int argc, const char* argv[])
{
    if (argc != 2) {
        log_error("para failed, simple: ./demo.h264 3840 2160");
        exit(EXIT_FAILURE);
    }
    SmartDrm drm;
    Timer* timer = Timer::get_instance();
    drm.init(1920, 1080, DRM_FORMAT_RGB888);
    SmartMppDecoder mpp_dec(MPP_VIDEO_CodingAVC);
    H264FileNaluPars h264_nalu;
    h264_nalu.init(argv[1], H264FileNaluPars::FMT_H264);
    RgaWrapper rga;
    RgaCfg rga_cmd = {
            1920, 1080, 1920, 1080,
            RK_FORMAT_YCrCb_420_SP, RK_FORMAT_RGB_888
        };
    rga.init(rga_cmd);
    fp = fopen("demo_2k.rgb", "wb");
    while (true) {
        getchar();
        
        printf("--------------- start ----------------\n");
        int ret;
        uint64_t size;
        uint8_t* ptr;
        ptr = drm.get_free_page(&size);
        
        
        log_debug("fread size[%d]", size);
        std::vector<uint8_t> vec = h264_nalu.get_nalu_frame();
        while (vec.size() < 1000) {
            std::vector<uint8_t> tmp_vec = h264_nalu.get_nalu_frame();
            if (tmp_vec.size() <= 0) {
                log_debug("h264 file read end.");
                fclose(fp);
                exit(EXIT_FAILURE);
            }
            vec.insert(vec.end(), tmp_vec.begin(), tmp_vec.end());
        }
        
        mpp_dec.sync_decoding(vec.data(), vec.size(), [&](uint8_t* frm_buf, uint32_t frm_len){
            fwrite(frm_buf, frm_len, 1, fp);
            log_debug("frame len: %d.", frm_len);
            if (frm_len == 0) {
                log_info("frame read nullptr.");
                return;
            }
            if (frm_len <= size) {  // 读取正常
                log_info("page_flip, drm size:%d, frame size:%d.", size, frm_len);
                rga.cvtColorImage(frm_buf, ptr);
                drm.set_page_flip();

                static uint32_t num = 0;
                printf("--------------- end:[%d] timer diff:%ld----------------\n", num++, timer->end());
                timer->begin();
            }
        });
    }

    log_debug("normal exit.");
    drm.deinit();
    return 0;
}